home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / dvtools / examples / programs / graph_query.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-08  |  23.8 KB  |  684 lines

  1. #ifndef lint
  2. static char SccsId[]= "@(#)graph_query.c    V1.8    3/13/95";
  3. #endif
  4. /*
  5. |    file name - graph_query.c
  6. |=========================================================================
  7. |
  8. |  This is an example program of how users can get an exact value off a
  9. |  particular point inside a graph. The program allows a user to display
  10. |  one of three types of graphs (line, point, or strip ) which display 50
  11. |  data points each time they update.  Updates occur when the user picks
  12. |  on an 'Update' button.  In between updates, the user can pick inside
  13. |  the graph's data area and then based on the location of the cursor, a
  14. |  vertical line is dropped at that time slot.  A digits graph is used to
  15. |  displays the exact value for that particular point.  The graphs are
  16. |  queried to retrieve the selected data slot and the data value of the
  17. |  vdp at the selected point.  This is accomplished using the feedback
  18. |  query flags defined for the module VPdgdfquery.
  19. |
  20. |=========================================================================
  21. */
  22. #include <windows.h>
  23. /*
  24.  *  DV-Tools header files
  25.  */
  26. #include "std.h"                /* <stdio.h> etc., scalar & macro definitions */
  27. #include "dvstd.h"              /* public types & constants */
  28. #include "dvtools.h"            /* constants used by T routines */
  29. #include "dvGR.h"               /* constants used by window mgt & GR routines */
  30. #include "VOstd.h"              /* constants used by VO & VOob routines */
  31. #include "Tfundecl.h"           /* T routines (screens, drawports & views) */
  32. #include "VOfundecl.h"          /* VO routines (objects) */
  33. #include "VUerfundecl.h"        /* VUer routines (event handling routines) */
  34. #include "VPfundecl.h"          /* VP routines (put info for dgp & vdp) */
  35. #include "VGfundecl.h"          /* VG routines (get info from dgp & vdp) */
  36. #include "GRfundecl.h"          /* GR routines (interface to display device) */
  37.  
  38. /* Constants */
  39. #define  DVPATH            (char *)NULL
  40. #define  DISPFORMS_STB     (char *)NULL
  41. #define  DVDEVICE          (char *)NULL
  42. #define  DVCOLORTABLE      (char *)NULL
  43. #define  VIEW_NAME         "graph_query.v"
  44. #define  SCREEN_VIEWPORT   (RECTANGLE *)NULL
  45. #define  DRAWING_VIEWPORT  (RECTANGLE *)NULL
  46.  
  47. /* Defines */
  48. #define MAIN_MENU       0
  49. #define GRAPH_MENU      1
  50. #define UPDATE          0
  51. #define QUIT            1
  52. #define NUM_GRAPHS      3
  53. #define LINE_GRAPH      0
  54. #define POINT_GRAPH     1
  55. #define STRIP_CHART     2
  56. #define NO_PREV_GRAPH (-1)
  57. #define FIRST_SLOT    1
  58.  
  59. /* Define the graph information structure */
  60. typedef struct
  61. {
  62.   OBJECT graph;                 /* Handle to graph object                */
  63.   DATAGROUP dgp;                /* Handle to graph's data group pointer  */
  64.   int slots;                    /* Number of slots in the graph          */
  65. } GRAPH_INFO;
  66.  
  67. /* Globals */
  68. DRAWPORT drawport;              /* how & where to display picture */
  69. VIEW view;                      /* picture representation of the view file */
  70. OBJECT CurrentValGraph;         /* digit graph to display data value */
  71. float *CurrentValue;            /* ptr to buffer for digit graph */
  72. int MainSel,                    /* buffer for main menu selection value */
  73.   CurrGraph,                    /* index representing the current graph */
  74.   PrevGraph,                    /* index representing the previous graph */
  75.   VpHeight,                     /* height of graph's data display area */
  76.   MarkerColor,                  /* color used by line marker */
  77.   MarkerStartX,                 /* x-coordinate of line marker start pt */
  78.   OldSlotNum;                   /* previous selected data slot */
  79. RECTANGLE ScreenVp;             /* graph's data display area */
  80. DV_POINT SlotSize;              /* size of single slot in a graph */
  81. ADDRESS Raster;                 /* raster array before marker drawn */
  82. int QuitProgram = NO;           /* flag to quit program */
  83. char *GraphName[NUM_GRAPHS] = {"line", "points", "strip"};
  84. GRAPH_INFO GraphInfo[NUM_GRAPHS];       /* saved information about graphs */
  85.  
  86. /* Functions defined in graph_query.c */
  87. void DisplaySlotValue V_P_((DV_POINT *picked_point));
  88. void UpdateScreen V_P_((int GraphChange));
  89. void InitStructures V_P_((void));
  90. void EraseLine V_P_((void));
  91. void DrawLineAtSlot V_P_((int selected_slot));
  92. int EventHandler V_P_((OBJECT client, EVENT_REQUEST request, int label, OBJECT loc, ADDRESS args));
  93.  
  94. /*------------------
  95.  *  DisplaySlotValue -- Determine the data value represented
  96.  *    on the graph at the user selected point. Update the
  97.  *    digit graph to display this data value.
  98.  */
  99. void 
  100. DisplaySlotValue (picked_point)
  101.      DV_POINT *picked_point;
  102. {
  103.   double dvalue;                /* value represented a selected point */
  104.   V_Q_PICK_VDP query_vdp;       /* query vdp for data information */
  105.  
  106.   /*
  107.    *  VPdgdfquery:  Queries a display formatter for information
  108.    *
  109.    *  V_Q_DATA_VALUE:         Gets a value of the vdp displayed
  110.    *                 at the point.
  111.    *
  112.    *  Obtain the data value of the vdp at the selected point.
  113.    *  In this example, all graphs have only one variable being
  114.    *  displayed.  If a graph displays more than one variable
  115.    *  then the below code would need to be changed to
  116.    *  obtain a data value for each of the variables at the
  117.    *  picked point.
  118.    */
  119.   query_vdp.vdp = (V_Q_VDP *) S_ALLOC (sizeof (V_Q_VDP));
  120.   query_vdp.location = *picked_point;
  121.   query_vdp.vdp->vdp = VGdgvd (GraphInfo[CurrGraph].dgp, 1);
  122.   query_vdp.vdp->index = 1;
  123.   VPdgdfquery (GraphInfo[CurrGraph].dgp, V_Q_DATA_VALUE,
  124.                (ADDRESS) & query_vdp, (ADDRESS) & dvalue);
  125.  
  126.   /*
  127.    *  Set the value to be displayed then update the digit graph.
  128.    */
  129.   *CurrentValue = (float) dvalue;
  130.   TdpDrawNextObject (drawport, CurrentValGraph);
  131.   S_FREE ((ADDRESS)query_vdp.vdp);
  132.  
  133. }
  134.  
  135.  
  136. /*--------------
  137.  *  UpdateScreen -- Update the screen by displaying the selected
  138.  *    graph. The line graph is the default graph to be displayed.
  139.  *    The display of the graph involves erasing and deleting the
  140.  *    previously displayed graph from the drawing if one exists
  141.  *    and adding the newly selected graph to the drawing, reading
  142.  *    data and displaying the graph.  The graph is updated for
  143.  *    for the number of samples assigned to the graph.
  144.  */
  145. void 
  146. UpdateScreen (GraphChange)
  147.      int GraphChange;
  148. {
  149.   OBJECT drawing;               /* graphical representation of screen */
  150.   DV_POINT fake_selected_point;    /* fake selection point */
  151.   int SlotOffset,               /* offset used to center marker on slot */
  152.     number_of_updates,          /* number of times to update the display */
  153.     i;                          /* counter */
  154.  
  155.   /* Obtain the drawing object from the view */
  156.   drawing = TviGetDrawing (view);
  157.  
  158.   /* Erase old indicator line if there is one */
  159.   if (Raster)
  160.     EraseLine ();
  161.  
  162.   /*
  163.    *  Erase and draw graphs as needed: Erase previous
  164.    *  graph if only the graph has changed since the last
  165.    *  update and there is actually a previous graph.
  166.    *  Then, delete the old graph from the drawing.
  167.    */
  168.   if (PrevGraph != NO_PREV_GRAPH && GraphChange)
  169.     {
  170.       TdpEraseObject (drawport, GraphInfo[PrevGraph].graph);
  171.       VOdrObDelete (drawing, GraphInfo[PrevGraph].graph);
  172.     }
  173.  
  174.   /*
  175.    *  Add the new graph to the drawing, read an iteration of data,
  176.    *  and draw the graph.
  177.    */
  178.   if (GraphChange)
  179.     {
  180.       VOdrObAdd (drawing, GraphInfo[CurrGraph].graph);
  181.       TviReadData (view);
  182.       TdpDrawObject (drawport, GraphInfo[CurrGraph].graph);
  183.     }
  184.  
  185.   /*
  186.    *  Read enough data to fill up the graph. This is based on the
  187.    *  number of samples assigned for the graph.
  188.    */
  189.   number_of_updates = (GraphChange) ? GraphInfo[CurrGraph].slots - 1
  190.     : GraphInfo[CurrGraph].slots;
  191.   for (i = 0; i < number_of_updates; i++)
  192.     {
  193.       TviReadData (view);
  194.       TdpDrawNextObject (drawport, GraphInfo[CurrGraph].graph);
  195.     }
  196.  
  197.   /*
  198.    *  Once the graph has been drawn and updated, obtain the slot size
  199.    *  and data display area information.
  200.    */
  201.   VPdgdfquery (GraphInfo[CurrGraph].dgp,
  202.                V_Q_SLOTSIZE, (ADDRESS)NULL, (ADDRESS) & SlotSize);
  203.   VPdgdfquery (GraphInfo[CurrGraph].dgp,
  204.                V_Q_DATAVP, (ADDRESS)NULL, (ADDRESS) & ScreenVp);
  205.  
  206.   /*
  207.    *  Determine the height of the data display area which will be
  208.    *  used when getting the raster before the line marker is
  209.    *  drawn.  The line marker designates the selected data slot.
  210.    *  Next, draw the indicator line at the first slot of the graph.
  211.    */
  212.   VpHeight = ScreenVp.ur.y - ScreenVp.ll.y;
  213.   if (CurrGraph != STRIP_CHART)
  214.     DrawLineAtSlot (FIRST_SLOT);
  215.   else
  216.     DrawLineAtSlot (0);
  217.  
  218.   /*
  219.    *  Display the slot value for the first slot in the graph.
  220.    *  Create a fake selection point to obtain the data value at
  221.    *  the graph's first data slot.
  222.    */
  223.   if (CurrGraph != STRIP_CHART)
  224.     SlotOffset = SlotSize.x / 2;
  225.   else
  226.     SlotOffset = 0;
  227.   fake_selected_point.x = ScreenVp.ll.x + SlotOffset;
  228.   fake_selected_point.y = ScreenVp.ll.y;
  229.   DisplaySlotValue (&fake_selected_point);
  230.  
  231.   /*  Set the previous graph to the current graph */
  232.   PrevGraph = CurrGraph;
  233. }
  234.  
  235.  
  236. /*----------------
  237.  *  InitStructures -- The module initializes necessary structures
  238.  *    used throughout the program based on information retrieved
  239.  *    from the view. The marker object, graph objects and input
  240.  *    objects are obtained and service result events are posted
  241.  *    for the input objects.
  242.  */
  243. void InitStructures ()
  244. {
  245.   OBJECT drawing,               /* graphical representation of screen */
  246.          object;                /* graphical object */
  247.   DATAGROUP dgp;                /* datagroup pointer of digits graph */
  248.   VARDESC vdp;                  /* variable descriptor of digits graph */
  249.   ADDRESS *vdplist;             /* variable descriptor list for input objects */
  250.   int numvars,                  /* number of vdps in list */
  251.       i;                        /* counter */
  252.  
  253.   /*
  254.    *  TviGetDrawing:  Gets a view's drawing object
  255.    */
  256.   drawing = TviGetDrawing (view);
  257.  
  258.   /*
  259.    *  Fill the GRAPH_INFO structure with the information on each
  260.    *  graph which may be displayed. The data group pointer and
  261.    *  slot count (samples) are saved in this structure.
  262.    *  The graphs are deleted from the drawing since only one will
  263.    *  ever be displayed at a time. Note: the reference count of
  264.    *  each object is increased before deleting the object from
  265.    *  the drawing. This is done to prevent the object from being
  266.    *  removed from the heap.  The currently selected graph will
  267.    *  be added back to the drawing which facilitates redrawing
  268.    *  for expose or resize events.
  269.    */
  270.   for (i = 0; i < NUM_GRAPHS; i++)
  271.     {
  272.       GraphInfo[i].graph = TdrGetNamedObject (drawing, GraphName[i]);
  273.       GraphInfo[i].dgp = VOdgGetDgp (GraphInfo[i].graph);
  274.       GraphInfo[i].slots = VGdgslots (GraphInfo[i].dgp);
  275.       VOobReference (GraphInfo[i].graph);
  276.       VOdrObDelete (drawing, GraphInfo[i].graph);
  277.     }
  278.  
  279.   /*
  280.    *  Obtain the digit graph which will be used to display
  281.    *  the picked value. Save the buffer pointer of the
  282.    *  data source variable attached to the graph.
  283.    */
  284.   CurrentValGraph = TdrGetNamedObject (drawing, "digits");
  285.   dgp = VOdgGetDgp (CurrentValGraph);
  286.   vdp = VGdgvd (dgp, 1);
  287.   CurrentValue = (float *) TdsvGetBuffer (TvdGetDataSourceVariable (vdp));
  288.  
  289.   /*
  290.    *  Rebind the graph menu vdp to the variable CurrGraph,
  291.    *  set the variable type to be integer and post a service
  292.    *  result request which will monitor selections in the
  293.    *  graph menu.  CurrGraph will represent the user's
  294.    *  selection for the particular graph to be displayed.
  295.    */
  296.   object = TdrGetNamedObject (drawing, "graph menu");
  297.   VOinGetVarList (object, &vdplist, &numvars);
  298.   TvdPutBuffer (vdplist[0], (ADDRESS) & CurrGraph);
  299.   VPvdtype (vdplist[0], V_I_TYPE);
  300.   VUerServiceResultPost ((OBJECT) GRAPH_MENU, EventHandler,
  301.                          (ADDRESS) NULL, 0, object, (int)INPUT_DONE, (int)GRAPH_MENU);
  302.  
  303.   /*
  304.    *  Rebind the main menu to the variable MainSel, set the
  305.    *  variable type to be integer and post a service result
  306.    *  request which will monitor selections in the main menu.
  307.    *  The main menu selections are Update and Quit.
  308.    */
  309.   object = TdrGetNamedObject (drawing, "main menu");
  310.   VOinGetVarList (object, &vdplist, &numvars);
  311.   TvdPutBuffer (vdplist[0], (ADDRESS) & MainSel);
  312.   VPvdtype (vdplist[0], V_I_TYPE);
  313.   VUerServiceResultPost ((OBJECT) MAIN_MENU, EventHandler,
  314.                          (ADDRESS) NULL, 0, object, (int)INPUT_DONE, (int)MAIN_MENU);
  315.  
  316.   /*
  317.    *  GRrgbtoindex:  Gets an index of a color in the color
  318.    *             lookup table. (255 255 0 = yellow)
  319.    *  Set the marker color which will be used for raster draws.
  320.    */
  321.   GRrgbtoindex (255, 255, 0, &MarkerColor);
  322. }
  323.  
  324. /*-----------
  325.  *  EraseLine -- Restore the raster taken before drawing the
  326.  *    line marker.  This raster will remove the drawn line
  327.  *    marker from the display.
  328.  */
  329. void EraseLine ()
  330. {
  331.   DV_POINT endpt1;
  332.  
  333.   /*
  334.    *  GRrasdraw:  Draws a raster to the selected device
  335.    *  GRrasfree:  Frees allocated storage area for raster
  336.    *
  337.    *  If a raster is defined, then restore it and free it.
  338.    */
  339.   if (Raster)
  340.     {
  341.       endpt1.x = MarkerStartX;
  342.       endpt1.y = ScreenVp.ll.y;
  343.       GRrasdraw (Raster, &endpt1);
  344.       GRrasfree (Raster);
  345.       Raster = (ADDRESS) NULL;
  346.     }
  347. }
  348.  
  349. /*----------------
  350.  *  DrawLineAtSlot --
  351.  */
  352. void 
  353. DrawLineAtSlot (selected_slot)
  354.      int selected_slot;
  355. {
  356.   DV_POINT endpt1, endpt2;
  357.   int SlotOffset;
  358.  
  359.   /*
  360.    *  Decrease the past slot number by one. The selected
  361.    *  slot number is a 1-based index. Subtracting one
  362.    *  is done since we will be determining from the
  363.    *  lower left corner of the data display area where
  364.    *  to draw the line marker.
  365.    *
  366.    *  If the current graph is the STRIP_CHART then do not
  367.    *  subtract one since the data flows from the right to
  368.    *  left.  The data value to be returned based on the
  369.    *  location will be the data value to the right of the
  370.    *  point. Therefore, we do not subtract one from the
  371.    *  number.
  372.    */
  373.   if (CurrGraph != STRIP_CHART)
  374.     selected_slot--;
  375.  
  376.   /*
  377.    *  The slot offset for most graphs will be half the width
  378.    *  of the time slot, i.e. we want to draw the vertical line
  379.    *  in the center of the time slot.  However for the strip
  380.    *  chart, the data points are drawn such that they are located
  381.    *  over the left edge of the time slots boundary, so there is
  382.    *  no offset.
  383.    */
  384.   if (CurrGraph != STRIP_CHART)
  385.     SlotOffset = SlotSize.x / 2;
  386.   else
  387.     SlotOffset = 0;
  388.  
  389.   /*
  390.    *  If there is a raster is already defined, then we need erase the
  391.    *  line and free the old raster.
  392.    */
  393.   if (Raster)
  394.      EraseLine ();
  395.  
  396.   /*  Determine the start point for the line marker.  */
  397.   endpt1.x = ScreenVp.ll.x + (SlotSize.x * selected_slot) + SlotOffset;
  398.   endpt1.y = ScreenVp.ll.y;
  399.  
  400.   /*
  401.    *  Save the slot number and x value, get the raster where the
  402.    *  line will be drawn, and draw the line in the marker color.
  403.    */
  404.   MarkerStartX = endpt1.x;
  405.   GRrasget (&endpt1, 1, VpHeight, &Raster);
  406.   GRcolor (MarkerColor);
  407.   endpt2.x = endpt1.x;
  408.   endpt2.y = ScreenVp.ur.y;
  409.   GRmove_and_vector (&endpt1, &endpt2);
  410.   GRflush ();
  411. }
  412.  
  413.  
  414. /*--------------
  415.  *  EventHandler -- Perform the appropriate action based on
  416.  *    the user's interaction with the particular menu
  417.  *    input object.  This function is called to control the
  418.  *    main menu and the graph selection menu.
  419.  *
  420.  */
  421. /*ARGSUSED*/
  422. int 
  423. EventHandler (client, request, label, loc, args)
  424.      OBJECT client;
  425.      EVENT_REQUEST request;
  426.      int label;
  427.      OBJECT loc;
  428.      ADDRESS args;
  429. {
  430.  
  431.   switch (label)
  432.     {
  433.       /* New graph selected */
  434.     case GRAPH_MENU:
  435.       UpdateScreen (YES);
  436.       break;
  437.  
  438.       /*
  439.        *  Check the main menu selection: call UpdateScreen if the user
  440.        *  selected to update the graph; otherwise the user selected to
  441.        *  quit the program.
  442.        */
  443.     case MAIN_MENU:
  444.       if (MainSel == UPDATE)
  445.         UpdateScreen (NO);
  446.       else
  447.         QuitProgram = YES;
  448.       break;
  449.     }
  450.  
  451.   return (int) INPUT_USED;
  452. }
  453.  
  454. /*
  455.  *   MAIN PROGRAM
  456.  */
  457. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
  458.                      LPSTR lpCmdLine, int nCmdShow )
  459. {
  460.   INT argc = 0;
  461.   CHAR **argv;
  462.   /*
  463.    *  program arguments
  464.    *    argv[1] - display device name (default is to use DVDEVICE)
  465.    */
  466.  
  467.   /* Define & initialize device name and view filename */
  468.   char *device_name = DVDEVICE; /* default device name */
  469.   char *view_name = VIEW_NAME;  /* default view name */
  470.  
  471.   OBJECT screen,                /* display device, the window */
  472.     location,                   /* the event representation */
  473.     drawing;                    /* graphical representation of screen */
  474.   DV_POINT *cur_loc;            /* screen coordinates of selected location */
  475.   int i,                        /* counter */
  476.     slot_num;                   /* data slot number */
  477.   int ResizeOccured = NO;   /* flag indicating resize event occurred */
  478.  
  479.   /*-----------------
  480.    *   Initialization
  481.    *
  482.    *   TInit:    perform the initialization of DV-Tools
  483.    *             TInit reads your configuration file and any
  484.    *             environment variables or logical names set.
  485.    */
  486.   make_argv(&argc,&argv,GetCommandLine());
  487.   TInit( DVPATH, DISPFORMS_STB );
  488.  
  489.   /*
  490.    *   TscOpenSet:  opens a device as a screen object using
  491.    *                specified attributes
  492.    *
  493.    *   Set exposure block to YES to insure the window
  494.    *   is ready for drawing when TdpDraw is called.
  495.    */
  496.   if (argc > 1)
  497.     device_name = argv[1];
  498.   screen = TscOpenSet (device_name, DVCOLORTABLE,
  499.                        V_X_EXPOSURE_BLOCK, YES,
  500.                        V_ACTIVE_CURSOR, V_END_OF_LIST);
  501.   if (!screen)
  502.     {
  503.       printf ("Must specify device on command line or");
  504.       printf (" in DataViews configuration file.\n");
  505.       S_EXIT (EXIT_ERR);
  506.     }
  507.  
  508.   /*
  509.    *   VOscWinEventMask:  sets the screen's window event mask
  510.    */
  511.   VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS |
  512.                             V_MOTIONNOTIFY | V_EXPOSE | V_RESIZE,
  513.             (ULONG) 0);
  514.  
  515.   /*
  516.    *   TviLoad:   Load a view in from a file,
  517.    *              user supplied view or default view of buffer.v
  518.    */
  519.   view = TviLoad (view_name);
  520.   if (!view)
  521.     {
  522.       printf ("Could not load view from file ");
  523.       printf ("%s.\n", view_name);
  524.       S_EXIT (EXIT_ERR);
  525.     }
  526.  
  527.   /*
  528.    *   TdpCreate: Create a drawport.
  529.    *              The drawport is attached to the screen object
  530.    *              specified while view specifies the view to be
  531.    *              displayed on the screen.
  532.    */
  533.   drawport = TdpCreate (screen, view, SCREEN_VIEWPORT, DRAWING_VIEWPORT);
  534.  
  535.   /* Initialize global variables */
  536.   PrevGraph = NO_PREV_GRAPH;
  537.   CurrGraph = 0;
  538.   slot_num = 0;
  539.   OldSlotNum = FIRST_SLOT;
  540.   Raster = (ADDRESS) NULL;
  541.  
  542.   /*
  543.    *  Prepare the view, open the data sources, draw
  544.    *  the drawport, and update the screen.
  545.    */
  546.   InitStructures ();
  547.   TviOpenData (view);
  548.   TdpDraw (drawport);
  549.   UpdateScreen (YES);
  550.  
  551.   /*---------------------
  552.    *    Control Loop
  553.    *
  554.    *    Poll the event queue for window events.  Events
  555.    *    occurring within input objects will be handled
  556.    *    through the event request handler VUerHandleLocEvent.
  557.    */
  558.   FOREVER
  559.   {
  560.     /*
  561.      *  VOloWinEventPoll:  Poll for the next window event.
  562.      *                     The polling mode used is V_WAIT.
  563.      *                     Therefore, VOloWinEventPoll does not
  564.      *                     return until a masked event is
  565.      *                     generated.  V_WAIT always produces
  566.      *                     a valid location object.
  567.      */
  568.     location = VOloWinEventPoll (V_WAIT);
  569.  
  570.     /*
  571.      *  VOloType:  returns the type of event.  These types
  572.      *             match event types specified in VOscWinEventMask.
  573.      */
  574.     switch (VOloType (location))
  575.       {
  576.  
  577.       case V_RESIZE:
  578.         /*
  579.          *  The window size has been changed.
  580.          *  TscReset:  Resets all screen drawports after
  581.          *             window resizing
  582.          *  Free the raster taken for the line drawn at the
  583.          *  selected slot. The screen will be redrawn so the
  584.          *  raster is no longer valid.
  585.          */
  586.         TscReset (screen);
  587.         GRrasfree (Raster);
  588.         Raster = (ADDRESS) NULL;
  589.         ResizeOccured = YES;
  590.         break;
  591.  
  592.       case V_EXPOSE:
  593.         /*
  594.          *  VOloRegion:  Returns a rectangle representing the
  595.          *               exposed region on the screen.
  596.          *  TscRedraw:   After erasing, redraws all the drawports
  597.          *               in the screen.
  598.          *  A portion of the window has been exposed and needs
  599.          *  to be redrawn.
  600.          */
  601.         TscRedraw (screen, VOloRegion (location));
  602.  
  603.         /* Obtain the new information concerning the data vp area of the graph.*/
  604.         if (ResizeOccured == YES)
  605.           {
  606.            /* GraphInfo[CurrGraph].dgp; */ /* statement with no effect */
  607.             VPdgdfquery (GraphInfo[CurrGraph].dgp,
  608.                          V_Q_DATAVP, (ADDRESS)NULL, (ADDRESS) & ScreenVp);
  609.             VPdgdfquery (GraphInfo[CurrGraph].dgp,
  610.                          V_Q_SLOTSIZE, (ADDRESS)NULL, (ADDRESS) & SlotSize);
  611.             VpHeight = ScreenVp.ur.y - ScreenVp.ll.y;
  612.             ResizeOccured = NO;
  613.           }
  614.  
  615.         DrawLineAtSlot (OldSlotNum);
  616.         break;
  617.  
  618.       case V_BUTTONPRESS:
  619.       case V_KEYPRESS:
  620.         if (VUerHandleLocEvent (location) == INPUT_UNUSED)
  621.           {
  622.             /*
  623.              *  If the screen location of the cursor is within the data area
  624.              *  of the graph, then determine which data slot was selected.
  625.              *  If the data slot has changed from the previous selection
  626.              *  then draw a new line marker and update the digit graph with
  627.              *  the data value at the selected slot.
  628.              *
  629.              *  V_Q_SLOT_AT_LOCATION:  Gets the 1-based index of the slot
  630.              *                 at the point.
  631.              */
  632.             cur_loc = VOloScpGet (location);
  633.             if (ScreenVp.ll.x <= cur_loc->x && cur_loc->x <= ScreenVp.ur.x &&
  634.             ScreenVp.ll.y <= cur_loc->y && cur_loc->y <= ScreenVp.ur.y)
  635.               {
  636.                 VPdgdfquery (GraphInfo[CurrGraph].dgp,
  637.                              V_Q_SLOT_AT_LOCATION, (ADDRESS)cur_loc,
  638.                  (ADDRESS) &slot_num);
  639.                 if (slot_num != -1 && slot_num != OldSlotNum)
  640.                   {
  641.                     OldSlotNum = slot_num;
  642.                     DrawLineAtSlot (slot_num);
  643.                     DisplaySlotValue (cur_loc);
  644.                   }
  645.               }
  646.           }
  647.         break;
  648.       }
  649.     if (QuitProgram == YES)
  650.       break;
  651.   }
  652.  
  653.   /*
  654.    *  Delete the current graph from the drawing. Then, dereference
  655.    *  all of the graph objects which will remove them from the heap.
  656.    *  This frees the memory for these objects. It is the responsibility
  657.    *  of the application to free the memory of all objects which are
  658.    *  maintained outside of the drawing object
  659.    */
  660.   drawing = TviGetDrawing (view);
  661.   VOdrObDelete (drawing, GraphInfo[CurrGraph].graph);
  662.   for (i = 0; i < NUM_GRAPHS; i++)
  663.     VOobDereference (GraphInfo[i].graph);
  664.  
  665.   /*--------------------
  666.    *   Termination
  667.    *
  668.    *   TscErase:     Erase the entire screen in the default
  669.    *                 background color
  670.    *   TdpDestroy:   Destroy the drawport,
  671.    *   TviCloseData: Close the data sources of the view
  672.    *   TviDestroy:   Destroy the view, freeing the allocated memory
  673.    *   TscCloseCurrentScreen:  Close the current display screen
  674.    *   TTerminate:   Perform the clean-up for DV-Tools
  675.    */
  676.   TscErase (screen);
  677.   TdpDestroy (drawport);
  678.   TviCloseData (view);
  679.   TviDestroy (view);
  680.   TscCloseCurrentScreen ();
  681.   TTerminate ();
  682.   return EXIT_OK;
  683. }
  684.